PurgeMemSys
PurgeMem
Purge blocks without compacting the heap void PurgeMem( bytesNeeded );
Size bytesNeeded ; size of contiguous block to locate PurgeMem performs a partial or complete purge of purgeable, unlocked,
relocatable blocks in the current heap zone. Purgeable blocks are removed
until a specified-size block is found or until all purgeable blocks are purged.
Compaction is not performed.
bytesNeeded is the size of a block you wish to allocate in a subsequent call to
block of memory becomes available or until the purge is complete. As
a Size type, it should be less than 16M (a 24-bit value). memFullErr (-108) A bytesNeeded -length block was not found
Notes: There is another routine, PurgeMemSys, which performs the equivalent operation to PurgeMem, but in the System heap zone. It takes the same
parameters as PurgeMem.
This may be faster than other functions that move blocks of memory (such
as CompactMem or MaxMem) in searching for free blocks. Only
relocatable blocks explicitly tagged as purgeable (see HPurge) and currently unlocked (see HUnlock) will be purged. PurgeMem does not allocate any memory.
Use PurgeSpace or MaxBlock to see how much memory will be obtained if you call PurgeMem.
The following information is from Apple's Macintosh Technical Note #303.
Inside Macintosh, Volume 2, page 23 briefly discusses purgeProc's. Most
applications will never need to use a purgeProc. However, if your
application requires the ability to maintain purgeable handles containing
data, or you need to have special notification when a certain handle is
purged, a purgeProc might help.
alert your application that it is getting ready to purge a given purgeable
handle. This warning is given so that you can save the data, or note for any
special reason that the data no longer exists. The purgeProc is passed the
handle that is being purged. It is up to you to determine if any action should
be taken on the handle. The interface looks like this:
pascal void myPurgeProc (Handle theHandle); Each zone has its own purgeProc pointer in its zone header. Each time the
Memory Manager prepares to purge a handle, it checks the zone header of the
zone that the handle belongs to, to determine if your application has
installed a purgeProc. If this field is not NIL, it calls the routine pointed to
with the handle being purged. This occurs for each handle being purged (not
every purgeable handle necessarily). When your routine is called, test the
handle passed to be sure that it is a handle you care about, then act on it.
Keep in mind that all handles that pass through your purgeProc may not be
expected, since your application can create purgeable handles in a few ways,
like calling HPurge on an existing handle, or loading a resource (the resource could have the purgeable attribute set), or by calling a routine
that could load a resource.
You install your own purgeProc by setting the field in your zone header.
Here is a sample routine that installs a purgeProc:
void InstallProc()
{
THz myZone;
myZone = GetZone(); /* recover my application's zone */ gOldProc = myZone->purgeProc; /* save the old purgeProc */
/* the name of the function is the address of the function */
myZone->purgeProc = myPurgeProc;
}
You must be sure to follow these rules regarding what a purgeProc must,
can, and cannot do...
• Do not rely on A5 being set to your application's globals. See
• Do not cause memory to be moved or purged.
• Do not open a file (but you can write to an already open file).
• Do not dispose of or change the purge status of the passed handle.
• Only use purgeProcs when absolutely necessary.
• Avoid using purgeProcs if you are also using the
• Use synchronous writes to data files.
• Preserve the contents of registers except A0-A2/D0/D1
• Use the FoldFolder feature of System 7.0 to locate the temporary
folder on the user's hard disk if you are creating a temporary file
to hold the contents of purged handles.
• Test the handle state first to determine if the handle belongs to the
Resource Manager, to weed out most handle purges that you don't
care about.
• Don't take too long to determine if the passed handle is in need of
purge notification (many programmers do not realize how often a
purgeProc is called).
Here is a pseudo code example that illustrates one possible use of the purge
warning procedure: saving the contents of the handle to a file before purging:
PurgeWarning( myHandleType theHandle)
SetUpApplicationA5World();
//if we get here, the handle does not belong to a resource
if(InSaveList( theHandle))
WriteData( theHandle);
}
Remember, the save file should probably be open at this point because opening a
file can cause memory to move. You will have to maintain a save list to indicate
purgeable handles that need saving.
If you plan to use the SetResPurge(true) option that allows you to modify purgeable resources (not a normal thing for applications to do). don't patch the
purgeProc pointer. If you do, remove your purgeProc, call SetResPurge, then re-install the purgeProc, making sure that it calls through to the Resource
Manager's routine after it is finished.